import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { UserSys } from "./userSys.entity";
import { FindOptionsWhere, IsNull, Repository } from "typeorm";
import { Http, NotFound, PasswordErr } from "src/util/http";
import { create_uid, cryptoPassword } from "src/util/crypto";
import { User } from "./user.entity";
import { System } from "src/system/system.entity";
import { RoleEnum } from "src/role/role.enum";
import { defaultAvatarPath, userAvatarPath } from "src/util/path";
import { existsSync } from "fs";



@Injectable()
export class UserService {
    constructor(
        @InjectRepository(UserSys)
        public userSys: Repository<UserSys>,
        @InjectRepository(User)
        public user: Repository<User>
    ) { }
    public getUserAvatarPath = (id: number) => {
        const path = userAvatarPath(id)
        if (existsSync(path)) return path;
        return defaultAvatarPath
    }

    public async create({
        phone,
        password = cryptoPassword("123456"),
        name,
        dingtalk = null,
        role = RoleEnum.member,
        dept = null,
        createAt = undefined,
        unique = false,
        ...rest
    }, system?: System) {
        const find = await this.userSys.findOne({ where: { account: phone }, relations: ["system", "user"] });
        if (!!find) {
            if (unique || !!find.system) throw Http.forbidden("用户已存在")
            return find;
        }
        const entity = this.userSys.create({
            system,
            account: phone,
            password,
            role,
            createAt,
            name,
            dept,
            dingtalk
        })
        const user = this.user.create({
            name,
            createAt,
            sex: !!rest.sex ? rest.sex + "" == "true" : undefined,
            isGuaduation: !!rest.isGuaduation ? rest.isGuaduation + "" == "true" : undefined,
            isAccommodation: !!rest.isAccommodation ? rest.isAccommodation + "" == "true" : undefined,
            signContract: !!rest.signContract ? rest.signContract + "" == "true" : undefined,
            confidentiality: !!rest.confidentiality ? rest.confidentiality + "" == "true" : undefined,
            isSignAccommodation: !!rest.isSignAccommodation ? rest.isSignAccommodation + "" == "true" : undefined,
            ...rest
        })
        entity.user = await this.user.save(user);
        return await this.userSys.save(entity);
    }

    public async findBy(where: FindOptionsWhere<UserSys>) {
        const entity = await this.userSys.findOne({
            where,
            relations: [
                // "user",
                "dept",
                "system"
            ]
        })
        return entity
    }
    public async findsBy(where: FindOptionsWhere<UserSys>) {
        const entity = await this.userSys.find({
            where,
            relations: [
                // "user",
                "dept",
                "system"
            ]
        })
        return entity
    }
    public async signup(account: string, password: string) {
        const result = await this.userSys.findOne({ where: { account }, relations: ["system"] });
        if (!result) throw NotFound
        if (!result.system && result.role !== RoleEnum.boos) throw NotFound;
        if (cryptoPassword(password) !== result.password) throw PasswordErr
        return result;
    }
}